import { describe, it, expect, beforeEach } from 'vitest';
import { createPinia, setActivePinia } from 'pinia';
import { useUploadStore } from '../../src/stores/uploadStore';
import imageUploadService from '../../src/services/ImageUploadService';
import { generateTestImages, generateTestImagesWithSizes, generateLargeTestImage } from './utils/imageGenerator';
import { measurePerformance, logPerformanceResult, runPerformanceTest } from './utils/performanceUtils';

describe('Image Upload Performance', () => {
  beforeEach(() => {
    // Create a fresh Pinia instance for each test
    setActivePinia(createPinia());
  });
  
  it('should measure upload performance with different image counts', async () => {
    // Test with different numbers of images
    const imageCounts = [5, 10, 20];
    
    for (const count of imageCounts) {
      // Generate test images
      const images = await generateTestImages(count, 800, 1200, 600, 900);
      
      // Calculate total pixels
      const totalPixels = images.reduce((sum, image) => {
        // We don't have access to image dimensions directly from the File object
        // So we'll estimate based on the filename which includes dimensions
        const match = image.name.match(/(\d+)x(\d+)/);
        if (match) {
          const width = parseInt(match[1]);
          const height = parseInt(match[2]);
          return sum + width * height;
        }
        return sum + 800 * 600; // Default estimate
      }, 0);
      
      // Measure performance
      const { performance } = await measurePerformance(
        `Upload ${count} images`,
        async () => {
          return await imageUploadService.uploadImages(images);
        },
        {
          imageCount: count,
          totalPixels,
          averageImageSize: totalPixels / count
        }
      );
      
      // Log performance result
      logPerformanceResult(performance);
      
      // Verify that the upload was successful
      expect(performance.duration).toBeGreaterThan(0);
    }
  });
  
  it('should measure upload performance with different image sizes', async () => {
    // Test with different image sizes
    const imageSizes: Array<[number, number]> = [
      [800, 600],    // Small: 0.48 MP
      [1600, 1200],  // Medium: 1.92 MP
      [3200, 2400]   // Large: 7.68 MP
    ];
    
    for (const [width, height] of imageSizes) {
      // Generate test images
      const images = await generateTestImagesWithSizes([[width, height]]);
      
      // Calculate total pixels
      const totalPixels = width * height;
      
      // Measure performance
      const { performance } = await measurePerformance(
        `Upload ${width}x${height} image (${(totalPixels / 1000000).toFixed(2)} MP)`,
        async () => {
          return await imageUploadService.uploadImages(images);
        },
        {
          imageCount: 1,
          totalPixels,
          width,
          height
        }
      );
      
      // Log performance result
      logPerformanceResult(performance);
      
      // Verify that the upload was successful
      expect(performance.duration).toBeGreaterThan(0);
    }
  });
  
  it('should measure upload performance with a large image', async () => {
    // Generate a large test image (8K resolution)
    const width = 7680;
    const height = 4320;
    const image = await generateLargeTestImage(width, height);
    
    // Calculate total pixels
    const totalPixels = width * height;
    
    // Measure performance
    const { performance } = await measurePerformance(
      `Upload large image (${width}x${height}, ${(totalPixels / 1000000).toFixed(2)} MP)`,
      async () => {
        return await imageUploadService.uploadImages([image]);
      },
      {
        imageCount: 1,
        totalPixels,
        width,
        height
      }
    );
    
    // Log performance result
    logPerformanceResult(performance);
    
    // Verify that the upload was successful
    expect(performance.duration).toBeGreaterThan(0);
  });
  
  it('should measure upload store performance', async () => {
    // Get upload store
    const uploadStore = useUploadStore();
    
    // Generate test images
    const images = await generateTestImages(10, 800, 1200, 600, 900);
    
    // Calculate total pixels
    const totalPixels = images.reduce((sum, image) => {
      // Estimate based on filename
      const match = image.name.match(/(\d+)x(\d+)/);
      if (match) {
        const width = parseInt(match[1]);
        const height = parseInt(match[2]);
        return sum + width * height;
      }
      return sum + 800 * 600; // Default estimate
    }, 0);
    
    // Measure performance
    const { performance } = await measurePerformance(
      'Upload store uploadImages',
      async () => {
        return await uploadStore.uploadImages(images);
      },
      {
        imageCount: images.length,
        totalPixels
      }
    );
    
    // Log performance result
    logPerformanceResult(performance);
    
    // Verify that the upload was successful
    expect(performance.duration).toBeGreaterThan(0);
    expect(uploadStore.images.length).toBe(images.length);
  });
});